//! 数据提供者主模块
//! 实现IDataProvider接口，提供数据库操作功能

use std::sync::Arc;

use async_trait::async_trait;
use mongodb::bson::{Bson, Document};
use serde_json::Value;
use tokio::sync::Mutex;

use crate::{
    models::{OperateResult, TokenModel},
    services::{IServiceProvider, ServiceProvider},
    storage::storage_provider::StorageProvider,
};
use crate::storage::storage_provider::{IStorage, IStorageExt};

/// 数据提供者接口定义
/// 对应C#版本DataProvider接口
#[async_trait]
pub trait IDataProvider: Send + Sync {
    /// 获取数据库信息
    async fn db_info(&self, token: &TokenModel) -> OperateResult;

    /// 执行数据库命令
    async fn command(&self, token: &TokenModel, cmd: Value) -> OperateResult;

    /// 复制集合
    async fn duplicate(&self, token: &TokenModel, source_collection: &str, destination_collection: &str) -> OperateResult;

    /// 创建快照
    async fn snapshot(&self, token: &TokenModel, collection_name: &str, data_period: &str) -> OperateResult;

    /// 销毁数据（软删除）
    async fn destroy(&self, token: &TokenModel, ids: Vec<String>) -> OperateResult;
}

/// 数据提供者实现类
/// 对应C#版本DataProvider类，实现IDataProvider接口
pub struct DataProvider {
    storage: Arc<dyn IStorage>,           // 存储实例，使用抽象接口
    services: Arc<dyn IServiceProvider>,   // 服务提供者
    logger: Arc<Mutex<()>>,               // 简化日志实现
}

impl DataProvider {
    /// 创建新的数据提供者实例
    pub async fn new() -> Result<Self, anyhow::Error> {
        let storage = StorageProvider::from_config().await?;
        Ok(Self {
            storage,
            services: Arc::new(ServiceProvider::new()),
            logger: Arc::new(Mutex::new(())),
        })
    }
    
    /// 使用指定的存储实例创建数据提供者
    pub fn with_storage(storage: Arc<dyn IStorage>) -> Self {
        Self {
            storage,
            services: Arc::new(ServiceProvider::new()),
            logger: Arc::new(Mutex::new(())),
        }
    }

    /// 常量定义 - 集合名称
    pub const THING_COLL_NAME: &'static str = "_system-things";        // 系统事物集合
    pub const CHANGE_COLL_NAME: &'static str = "_system-things-changed"; // 事物变更集合
    pub const SNAPSHOT_COLL_NAME: &'static str = "_system-things-snapshot"; // 快照集合
    pub const INSTANCE_COLL_NAME: &'static str = "work-instance";      // 工作实例集合
    pub const GOODS_COLL_NAME: &'static str = "goods-sync";           // 商品同步集合
    pub const ORDER_COLL_NAME: &'static str = "mall-order";            // 商城订单集合

    /// 获取存储实例的克隆
    pub fn storage(&self) -> Arc<dyn IStorage> {
        self.storage.clone()
    }

    /// 获取对象（内部方法）
    async fn get_object(&self, token: &TokenModel, key: &str) -> Option<Value> {
        // 实现获取对象的逻辑
        let _ = token; // 标记为已使用，待实现实际逻辑
        let _ = key;   // 标记为已使用，待实现实际逻辑
        None
    }
}

#[async_trait]
impl IDataProvider for DataProvider {
    async fn db_info(&self, token: &TokenModel) -> OperateResult {
        match self.storage.run_command(&token.db_name(), Document::new()).await {
            Ok(doc) => OperateResult::success(serde_json::to_value(doc).unwrap_or(Value::Null)),
            Err(e) => OperateResult::fail(&format!("获取数据库信息失败: {}", e)),
        }
    }

    async fn command(&self, token: &TokenModel, cmd: Value) -> OperateResult {
        // 将Value转换为BSON Document
        let bson_cmd = match mongodb::bson::to_document(&cmd) {
            Ok(doc) => doc,
            Err(e) => return OperateResult::fail(&format!("命令格式错误: {}", e)),
        };

        match self.storage.run_command(&token.db_name(), bson_cmd).await {
            Ok(doc) => OperateResult::success(serde_json::to_value(doc).unwrap_or(Value::Null)),
            Err(e) => OperateResult::fail(&format!("执行命令失败: {}", e)),
        }
    }

    async fn duplicate(&self, token: &TokenModel, source_collection: &str, destination_collection: &str) -> OperateResult {
        // 实现集合复制逻辑
        // 这里需要执行MongoDB的聚合管道 $out 操作
        let pipeline = vec![Document::from_iter([("$out".to_string(), Bson::String(destination_collection.to_string()))])];

        match self.storage.aggregate(&token.db_name(), source_collection, pipeline).await {
            Ok(_) => OperateResult::success(Value::Null),
            Err(e) => OperateResult::fail(&format!("复制集合失败: {}", e)),
        }
    }

    async fn snapshot(&self, token: &TokenModel, collection_name: &str, data_period: &str) -> OperateResult {
        let destination_name = format!("{}_ {}", collection_name, data_period);
        self.duplicate(token, collection_name, &destination_name).await
    }

    async fn destroy(&self, token: &TokenModel, ids: Vec<String>) -> OperateResult {
        let filter = mongodb::bson::doc! {
            "id": {"$in": ids}
        };
        let update = mongodb::bson::doc! {
            "$set": {"isDeleted": true}
        };

        match self.storage.update_many(&token.db_name(), Self::THING_COLL_NAME, filter, update).await {
            Ok(_) => OperateResult::success(Value::Null),
            Err(e) => OperateResult::fail(&format!("销毁数据失败: {}", e)),
        }
    }
}

/// 单例模式实现
/// 对应C#版本ISingleton接口
#[async_trait]
pub trait ISingleton {
    async fn init_once(&self) -> Result<(), Box<dyn std::error::Error>>;
}

#[async_trait]
impl ISingleton for DataProvider {
    async fn init_once(&self) -> Result<(), Box<dyn std::error::Error>> {
        // 初始化逻辑
        Ok(())
    }
}